home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-02-26 | 9.8 KB | 362 lines | [TEXT/MPS ] |
- { }
-
- PROGRAM TimeBaseSlave;
- {
- Shows how to enslave time bases
- and also how to create and use time base call back routines.
- }
-
- USES
- MemTypes, QuickDraw, OSIntf, ToolIntf, PackIntf, Traps, GestaltEqu,
- Movies, QuickTimeComponents,FixMath;
-
- LABEL 123;
-
- CONST MoviePieces = 4; (* number of movie pieces *)
- kMinDuration = 25; (* minimun movie duration *)
-
- VAR gMCPlay: MovieController;
- gWind: WindowPtr;
- wRect: Rect;
- gMoov: Array [1..4] OF Movie;
- gSystemVersion: Integer;
- gForwardFlag,
- gDoneFlag: Boolean;
- gErr: OSErr;
- gResult,
- enslaving: Boolean;
- gEventRec: EventRecord;
- reply: StandardFileReply;
- doneSizing: Boolean;
- i, stage: Integer;
-
- {$I TimeBaseSlaveAux.p} { Includes all auxiliary routines. }
-
- FUNCTION GetMovie: OSErr;
- {
-
- purpose get a movie from the selected file.
- extend the movie duration is needed.
- make copies of the movie to have movies to enslave.
- NOTE: CopyMovieSelection creates an inactive movie; to make it
- play you have to make it active.
- }
-
- VAR where: Point;
- err: OSErr;
- movieResFile,
- resID, i: Integer;
- wasChanged: Boolean;
- moovResName: Str255;
- moovDuration: TimeValue;
-
- BEGIN
- err := fnfErr; { This is as good an error as any other }
-
- err := OpenMovieFile(reply.sfFile, movieResFile, fsRdPerm);
- IF err = noErr THEN
- resID := 0; { First 'moov' found }
- err := NewMovieFromFile( gMoov[1], movieResFile, resID, moovResName, newMovieActive, wasChanged);
- IF CloseMovieFile(movieResFile) <> noErr THEN
- ErrorControl('Could not close the file');
-
- ExtendMovie(gMoov[1]); (* make sure movie is long enough *)
-
- moovDuration := GetMovieDuration(gMoov[1]);
- SetMovieSelection(gMoov[1], 0, moovDuration); (* select whole movie *)
-
- FOR i := 2 TO MoviePieces DO
- BEGIN
- gMoov[i] := CopyMovieSelection(gMoov[1]); (* clone the movie *)
- err := GetMoviesError;
- IF err <> noErr THEN ErrorControl('SetMovieBox failed');
- SetMovieActive(gMoov[i], TRUE);
- END;
-
- GetMovie := err;
- END;
-
- FUNCTION SetUpMovie(moov: Movie; wind: WindowPtr): OSErr;
- {
-
- purpose given a window, a movie this routine sizes the
- window to fit the movie.
- }
-
- VAR
- err: OSErr;
- moovBox,
- cBox: Rect;
- m: Movie;
-
- BEGIN
-
- { The movie box may come with negative coordinates so we reset the
- origin to 0,0 }
- GetMovieBox(moov,moovBox);
- OffsetRect(moovBox, -moovBox.left, -moovBox.top);
- SetMovieBox(moov, moovBox);
- err := GetMoviesError;
- IF err <> noErr THEN ErrorControl('SetMovieBox failed');
-
- IF NOT doneSizing THEN { We want to resize the window just once }
- BEGIN
- { Resize window to the dimensions of the movie }
- SizeWindow(wind, moovBox.right-moovBox.left,moovBox.bottom-moovBox.top,true);
- ShowWindow(wind);
- doneSizing := TRUE;
- END;
-
- { Tell the movie toolbox where to display the movie,
- also we want to start from the begining
- and set the movie in motion.
- }
-
- SplitMovie(moov, i);
-
- SetMovieGWorld(moov, CGrafPtr(wind), NIL);
- err := GetMoviesError;
- IF err <> noErr THEN ErrorControl('SetMovieGWorld failed');
-
- IF ((i = 1) OR (NOT enslaving)) THEN { we do this only for the first movie if }
- BEGIN { time bases are being enslaved }
- GotoBeginningOfMovie(moov);
- err := GetMoviesError;
- IF err <> noErr THEN ErrorControl('GotoBeginningOfMovie failed');
- (*
- StartMovie(moov);
- err := GetMoviesError;
- IF err <> noErr THEN ErrorControl('StartMovie failed'); *)
- END;
- SetUpMovie := err;
- END;
-
- PROCEDURE KillMovieSoundTracks(moov: Movie);
- VAR trackCount,
- counter: Integer;
- atrack: Track;
- creator: Str255;
- mediaType,
- manuf: OSType;
- err: OSErr;
-
- BEGIN
- trackCount := GetMovieTrackCount(moov);
-
- FOR counter := 1 to trackCount DO
- BEGIN
- aTrack := GetMovieIndTrack(moov, counter);
- GetMediaHandlerDescription(GetTrackMedia(aTrack), mediaType, creator, manuf);
- err := GetMoviesError;
- IF err <> noErr THEN
- DebugStr('Error at GetMediaHandlerDescription');
- IF mediaType = 'soun' THEN
- BEGIN
- DisposeMovieTrack(aTrack);
- err := GetMoviesError;
- IF err <> noErr THEN
- DebugStr('Error at disposing tracks');
- END;
- END
- END;
-
- (* The routine called when the call back event occurs.
- refCon contains the time that triggered the event.
- Note that the A5 world is set up by the movie toolbox
- so globals and such are readily available.
- *)
- PROCEDURE FlipPieces(cb: QTCallBack; refCon: LONGINT);
- VAR j: Integer;
- callWhen: LONGINT;
- scale: TimeScale;
- stop: LONGINT;
- tr: TimeRecord;
- tb: TimeBase;
- err: OSErr;
- BEGIN
-
- stage := (stage + 1) MOD 4;
-
- FOR j:= 1 TO MoviePieces DO
- BEGIN
- ShiftMoviePieces(j);
- END;
- (* Time to reprime the callback. We want to be called in
- three seconds, unless that would put us after the end of the movie.*)
- tb := GetCallBackTimeBase(cb);
- scale := 600; (* 100 units in this scale mean one second *)
- callWhen := refCon + (3*scale); (* call me in 3 seconds *)
- stop := GetTimeBaseStopTime(tb, scale, tr);
- IF callWhen > stop THEN (* wrap around the three seconds *)
- callWhen := GetTimeBaseStartTime(tb, scale, tr) + callWhen - stop;
-
- { callWhen := GetTimeBaseStartTime(tb, scale, tr);
- }
- err := CallMeWhen(cb, @FlipPieces, callWhen, triggerTimeFwd+callBackAtInterrupt, callWhen, scale);
- { err := CallMeWhen(cb, @FlipPieces, when, triggerTimeFwd, when, scale);
- }
- END;
-
- (* Here we create a TimeBase call back that will allow us to flip
- the movies at regular intervals.
- *)
- FUNCTION SetCallBack: OSerr;
-
- VAR err : OSErr;
- cb: QTCallBack;
- tb: TimeBase;
- when: LONGINT;
- scale: TimeScale;
-
- BEGIN
- tb := GetMovieTimeBase(gMoov[1]); { get time base of first movie }
- err := GetMoviesError;
- IF err <> noErr THEN ErrorControl('GetMovieTimeBase failed');
- (* want to be called at regular intervals so we use the callBackAtTime type;
- note that if the high bit is set then the call back occurs at interrupt time,
- this is not necessary here.
- *)
- cb := NewCallBack(tb, callBackAtTime);
-
- (* CallMeWhen primes the task and sets the routine that has to be called *)
- scale := 100; (* 100 units in this scale mean one second *)
- when := 3 * scale; (* call me in 3 seconds *)
-
- err := CallMeWhen(cb, @FlipPieces, when, triggerTimeFwd, when, scale);
- IF err <> noErr THEN
- DebugStr('CallMeWhen failed');
- END;
-
- FUNCTION EnslaveMovies: OSerr;
-
- VAR err: OSErr;
- masterTimeBase: TimeBase;
- slaveZero: TimeRecord;
- slaveZeroTV: TimeValue;
- masterScale: TimeScale;
- count: Integer;
- BEGIN
- IF NOT enslaving THEN EXIT(EnslaveMovies); { nothing to do here }
-
- err := noErr;
-
- masterTimeBase := GetMovieTimeBase(gMoov[1]); { get time base of first movie }
- err := GetMoviesError;
- IF err <> noErr THEN ErrorControl('GetMovieTimeBase failed');
-
- masterScale := GetMovieTimeScale(gMoov[1]); { needed for SetMovieMasterTimeBase }
- err := GetMoviesError;
- IF err <> noErr THEN ErrorControl('GetMovieTimeScale failed');
-
- slaveZeroTV := GetTimeBaseStartTime(masterTimeBase, masterScale, slaveZero); { ditto }
- err := GetMoviesError;
- IF err <> noErr THEN ErrorControl('GetMovieTimeScale failed');
- FOR count := 2 TO 4 DO
- BEGIN
- SetMovieMasterTimeBase(gMoov[count], masterTimeBase, slaveZero); { now we do it }
- err := GetMoviesError;
- IF err <> noErr THEN
- BEGIN
- ErrorControl('SetMovieMasterTimeBase failed');
- LEAVE;
- END;
- { Since we are here we'll shut up all slave movies, there is only one sound anyway }
- KillMovieSoundTracks(gMoov[count]);
- END;
-
- EnslaveMovies := err;
- END;
-
- PROCEDURE DoUpdate(theEvent : EventRecord);
- {
- purpose responds to update events
- }
- BEGIN
- BeginUpdate(WindowPtr(theEvent.message));
- SetPort(WindowPtr(theEvent.message));
-
- IF UpdateMovie(gMoov[1]) <> noErr THEN
- ErrorControl('UpdateMovie failed');
-
- EndUpdate(WindowPtr(theEvent.message));
- END; (* DoUpdate *)
-
- BEGIN (* QTSample *)
-
- IF InitSystem <> noErr THEN { Initialize all managers }
- BEGIN
- ErrorControl('Initialization failed');
- Exit(PROGRAM);
- END;
-
- gWind := NewCWindow(NIL, wRect, 'TimeBaseSlave Window', false, noGrowDocProc,
- WindowPtr(-1), true, 0);
-
- SetPort(gWind); { Make our window the current port }
-
- 123:InitVars;
- IF DisplayGetFile('Please select movie file:',reply) THEN{ ask user to select a movie file }
- BEGIN
- gErr := GetMovie; (* get movie and replicate it *)
- END
- ELSE
- gErr := fnfErr;
-
- IF gErr <> noErr THEN
- ErrorControl('Could not get the movie, Bye!;g')
- ELSE { if we have a movie then continue }
- BEGIN
- FOR i:= 1 TO MoviePieces DO
- BEGIN
- gErr := SetUpMovie(gMoov[i],gWind);
- IF gErr <> noErr THEN LEAVE;
- END;
-
- gErr := EnslaveMovies;
-
- gErr := SetCallBack;
-
- StartMovie(gMoov[1]);
- gErr := GetMoviesError;
- IF gErr <> noErr THEN ErrorControl('StartMovie failed');
-
- IF gErr <> noErr THEN
- ErrorControl('Error at SetUpMovie')
- ELSE
- BEGIN
- WHILE NOT gDoneFlag DO
- BEGIN
- gResult := GetNextEvent(everyEvent, gEventRec);
- IF gResult THEN
- HandleEvent(gEventRec) { Cliks in go away terminate movie }
- ELSE
- BEGIN
- FOR i := 1 TO MoviePieces DO
- MoviesTask(gMoov[i], doTHeRIghtThing); (* doTHeRIghtThing) *)
- IF IsMovieDone(gMoov[1]) THEN
- BEGIN
- { if using slaves then moving the master to the
- begining moves the others also
- }
- SysBeep(1);
- IF enslaving THEN
- GoToBeginningOfMovie(gMoov[1])
- ELSE
- BEGIN
- { if not all have to be done one by one }
- DebugStr('we are not enslaving');
- FOR i:= 1 TO MoviePieces DO
- GoToBeginningOfMovie(gMoov[i]);
- END
- END;
- END
- END
- END;
- { NEVER, EVER dispose the master movie first!!!! }
- FOR i:=MoviePieces DOWNTO 1 DO
- DisposeMovie(gMoov[i]);
- GOTO 123;
- END;
- DisposeWindow(gWind);
- ExitMovies;
- END.